package com.huafeng.security;

import com.alibaba.fastjson2.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.huafeng.commonutil.IpUtils;
import com.huafeng.commonutil.JwtHelper;
import com.huafeng.model.base.Result;
import com.huafeng.model.entity.SysLoginLog;
import com.huafeng.model.enums.ResultCodeEnum;
import com.huafeng.model.vo.LoginVo;
import com.huafeng.commonutil.ResponseUtils;
import com.huafeng.service.SysLoginLogService;
import org.springframework.http.HttpEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;

/**
 * @author 花风
 * @date 2023/8/20 18:41
 * @Description 自定义登录拦截器
 */
public class TokenLoginFilter extends UsernamePasswordAuthenticationFilter {
    private final SysLoginLogService sysLoginLogService;

    public TokenLoginFilter(AuthenticationManager authenticationManager, SysLoginLogService sysLoginLogService) {
        this.setAuthenticationManager(authenticationManager);
        this.setPostOnly(false);
        //指定登录接口及提交方式，可以指定任意路径
        this.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/admin/system/sysUser/login","POST"));
        this.sysLoginLogService = sysLoginLogService;
    }

    // 登录验证
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        try {
            // 从请求中获取登录对象
            LoginVo loginVo = new ObjectMapper().readValue(request.getInputStream(), LoginVo.class);
            // 创建Authentication对象
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginVo.getUsername(), loginVo.getPassword());
            return this.getAuthenticationManager().authenticate(authenticationToken);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    // 验证成功
    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
        CustomUser user = (CustomUser) authResult.getPrincipal();
        // 生成token
        String token = JwtHelper.createToken(user.getSysUser().getId(), user.getUsername());
        // 记录登录日志
        sysLoginLogService.recordLoginLog(user.getUsername(),0,IpUtils.getIp(request),"登录成功");
        // 写回token
        ResponseUtils.out(response, Result.ok(Map.of("token",token)));
    }

    // 验证失败
    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed){
        sysLoginLogService.recordLoginLog(null,1,IpUtils.getIp(request),"登录失败");
        if(failed.getCause() instanceof RuntimeException) {
            ResponseUtils.out(response, new Result(failed.getMessage(),204));
        } else {
            ResponseUtils.out(response, new Result(ResultCodeEnum.LOGIN_MOBLE_ERROR));
        }
    }
}
